/*
 *  atBudget Personal Finance Management application
 *
 *  Copyright 2011, Ilia Frenkel <frenkel.ilia@gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
	Categories controller handles all interactions with categories.
 */
Ext.define('ATB.controller.Categories', {
    extend: 'Ext.app.Controller',
	views: [
		'category.List',
		'category.Create',
		'category.Edit',
		'category.Manage',
		'category.Select'
	],
	stores: [
		'Categories'
	],
	models: [
		'Category'
	],
	/*
		Setup event handlers.
	*/
    init: function() {
		this.control({
			'categorymanage': {
				show: this.refreshStore
			},
			'categorymanage button[action=addcategory]': {
				click: this.openNewCategory
			},
			'categorymanage button[action=editcategory]': {
				click: this.openEditCategory
			},
			'categorymanage button[action=deletecategory]': {
				click: this.deleteCategory
			},
			'categorymanage categorylist': {
				selectionchange: this.setButtonsState
			},
			'categorycreate button[action=save]': {
				click: this.createCategory
			},
			'categoryedit button[action=save]': {
				click: this.updateCategory
			},
			'categorylist': {
				itemdblclick: this.editCategory
			}
		});//this.control
    },//init

	/*
		Open new category dialogue. Nothing exciting here - just create
		the view.
	*/
	openNewCategory: function(button) {
		var win  = button.up('window');
		var sel  = win.down('categorylist').getView().selModel.selected.items;
		if (sel.length <= 0) {
			var record = this.getCategoryModel().create({id:0,parentid:0});
		} else {
			var parent = sel[0];
			while ((parent) && (parent.data.parentid != 0)) {
				parent = parent.parentNode;
			}
			var record = this.getCategoryModel().create({id:0,parentid:parent.data.id});
		}
		
		var view = Ext.widget('categorycreate');
		view.down('form').loadRecord(record);
	},//openNewCategory
	
	/*
		An event handler for "Save" button in the create category dialogue.
		Collects the values from the form, create new record, adds it to
		the store and calls	sync on the store which triggers communication
		with the server. Any error during the communication is handled by 
		the model's proxy.
	*/
	createCategory: function(button) {
		var win    = button.up('window'),
			form   = win.down('form'),
			values = form.getValues(),
			store  = this.getCategoriesStore();
		
		var record = this.getCategoryModel().create(values);
		record.data.leaf = true;
		record.data.iconCls = 'atb-no-icon';

		if (record.data.parentid != 0 ) {
			var root = store.getNodeById(record.data.parentid);
		} else {
			var root = store.getRootNode();
		}
		//root.appendChild(root.createNode(record));
		root.appendChild(record);
		record.save();
		/* !!! I don't understand why I have to do this, but if I don't ExtJs
		   sends an empty root record to the server (all fields are NULLs)   */
		store.getRootNode().phantom = false;

		//store.sync();
		root.expand();
		win.close();
	},//createCategory

	/*
		Open edit category dialogue and load category information.
		This is an event handler for categories tree double click action.
		Parameters:
			grid   - grid panel that the user double clicked
			record - category record that the user double clicked on
	*/
	editCategory: function(grid, record) {
		var view = Ext.widget('categoryedit');
		view.down('form').loadRecord(record);
	},//editCategory
	
	/*
		The same as editCategory but for "Edit" button on the toolbar.
		Since we don't have reference to the grid or selected record
		we have to find out which record is selected and then call 
		editAccount method. If no records are selected an error message
		will be shown.
	*/
	openEditCategory: function (button) {
		var win  = button.up('window'),
			grid = win.down('categorylist'),
			sel  = grid.getSelectionModel(),
			recs = sel.selected;
			if (recs.items.length <= 0) {
				Ext.Msg.alert('Error', 'Please select one of the categories first.');
			} else {
				this.editCategory(grid, recs.items[0]);
			}
	},//openEditCategory

	/*
		An event handler for "Save" button in the edit category dialogue.
		Collects the values from the form, updates the record and calls
		sync on the store which triggers communication with the server.
		Any error during the communication is handled by the model's proxy.
	*/
	updateCategory: function(button) {
		var win    = button.up('window'),
			form   = win.down('form'),
			record = form.getRecord(),
			values = form.getValues();

		record.set(values);
		//this.getCategoriesStore().sync();
		record.save();
		win.close();
	},//updateCategory
	
	/*
		An event handler for "Remove" button in the manage categories dialogue.
		Asks for confirmation and if positive destroys the selected record.
		Any error during the communication is handled by the model's proxy.
	*/
	deleteCategory: function(button) {
		var win    = button.up('window'),
			grid = win.down('categorylist'),
			sel  = grid.getSelectionModel(),
			recs = sel.selected;
		if (recs.items.length <= 0) {
			Ext.Msg.alert('Error', 'Please select one of the categories first.');
		} else {
			var record = recs.items[0];
			Ext.Msg.show({
				title:'Please confirm',
				msg: 'Are you sure you want to delete this category?',
				buttons: Ext.Msg.YESNO,
				fn: function(buttonId) {
					if (buttonId == 'yes') {
						record.destroy();
					}
				},
				icon: 'atb-icon-question'
			});
		}
	},//deleteCategory

	/*
		Event handler for categories tree. Disables/enables "Edit" and "Remove"
		buttons according to selection.
	*/
	setButtonsState: function(view, sel, opts) {
		var win    = view.view.up('window'),
			edtBtn = win.down('button[action=editcategory]'),
			delBtn = win.down('button[action=deletecategory]')
		if (sel.length > 0) {
			edtBtn.enable();
			delBtn.enable();
		} else {
			edtBtn.disable();
			delBtn.disable();
		}
	},//setButtonsState

	/*
		Refresh categories store when manage payees dialogue is shown to
		fetch any changes from the server before we make new ones.
	*/
	refreshStore: function() {
		var store = this.getCategoriesStore();
		/* !!! I don't understand why I have to do this, but if I don't ExtJs
		   sends an empty root record to the server (all fields are NULLs)   */
		store.getRootNode().phantom = false;
		store.sync();
	}//refreshStore
});